package com.dullwolf.utils.osu;

import com.dullwolf.model.Osu;
import com.dullwolf.utils.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class OSUApi {

    private Osu osuDao = new Osu();

    public String sendOsuApi(String username, int ll, int pc, int tth, String ranks, String accs, String pps, String rankeds, int mode,boolean update) {
        String str;
        double pp;
        double acc;
        int rank;
        long ranked;
        List<Map> info = JsonUtils.getArrayByJson(ApiUtil.getOsuApiStr(username, mode), Map.class);
        if (ArrayUtil.isNotEmpty(info)) {
            if (null == info.get(0).get("playcount")) {
                return "玩家主页：https://osu.ppy.sh/u/" + info.get(0).get("user_id") + "\n" +
                        "这家伙在该模式中很久没玩过了>.<";
            }
            Osu myOSU = selInfoByUserId(Long.parseLong(info.get(0).get("user_id").toString()), mode);
            if (null == myOSU) {
                //用户是第一次使用，数据库不存在，于是执行插入
                Map<String, Object> m = new HashMap<>();
                m.put("userId", info.get(0).get("user_id"));
                m.put("acc", acc(info.get(0).get("accuracy").toString()));
                m.put("level", (int) Double.parseDouble(info.get(0).get("level").toString()));
                m.put("pc", info.get(0).get("playcount"));
                m.put("pp", acc(info.get(0).get("pp_raw").toString()));
                m.put("rank", info.get(0).get("pp_rank"));
                m.put("tth", add(info.get(0).get("count300").toString(), info.get(0).get("count100").toString(), info.get(0).get("count50").toString()));
                m.put("username", info.get(0).get("username"));
                m.put("mode", mode);
                m.put("ranked", info.get(0).get("ranked_score"));
                insertData(m);

            } else {
                if (update) {
                    //需要更新
                    myOSU.setAcc(Double.parseDouble(acc(info.get(0).get("accuracy").toString())));
                    myOSU.setLevel((int) Double.parseDouble(info.get(0).get("level").toString()));
                    myOSU.setPc(Integer.parseInt(info.get(0).get("playcount").toString()));
                    myOSU.setPp(Double.parseDouble(acc(info.get(0).get("pp_raw").toString())));
                    myOSU.setRank(Integer.parseInt(info.get(0).get("pp_rank").toString()));
                    myOSU.setTth(add(info.get(0).get("count300").toString(), info.get(0).get("count100").toString(), info.get(0).get("count50").toString()));
                    myOSU.setUserId(Long.parseLong(info.get(0).get("user_id").toString()));
                    myOSU.setUsername(info.get(0).get("username").toString());
                    myOSU.setUpdateTime(new Date());
                    myOSU.setRankscore(info.get(0).get("ranked_score").toString());
                    myOSU.update();
                }
                ll = (int) Double.parseDouble(info.get(0).get("level").toString()) - myOSU.getLevel();
                pp = Double.parseDouble(acc(info.get(0).get("pp_raw").toString())) - myOSU.getPp();
                if (pp < 0) {
                    pps = "-" + acc("" + (-1) * pp);
                } else {
                    pps = "+" + acc("" + pp);
                }
                acc = Double.parseDouble(acc(info.get(0).get("accuracy").toString())) - myOSU.getAcc();
                if (acc < 0) {
                    accs = "-" + acc("" + (-1) * acc);
                } else {
                    accs = "+" + acc("" + acc);
                }
                pc = Integer.parseInt(info.get(0).get("playcount").toString()) - myOSU.getPc();
                tth = add(info.get(0).get("count300").toString(), info.get(0).get("count100").toString(), info.get(0).get("count50").toString()) - myOSU.getTth();
                rank = Integer.parseInt(info.get(0).get("pp_rank").toString()) - myOSU.getRank();
                if (rank <= 0) {
                    ranks = "↑" + (-1) * rank;
                } else {
                    ranks = "↓" + rank;
                }

                ranked = Long.parseLong(info.get(0).get("ranked_score").toString()) - Long.parseLong(myOSU.getRankscore());
                if (ranked < 0) {
                    rankeds = "-" + StringUtil.fen(((-1) * ranked) + "");
                } else {
                    rankeds = "+" + StringUtil.fen(ranked + "");
                }
            }
            String modes = CmdUtil.getModeName(mode);

            String fen = 100 - (Double.parseDouble(info.get(0).get("level").toString()) - (int) Double.parseDouble(info.get(0).get("level").toString())) * 100 + "";

            str = "主页：https://osu.ppy.sh/u/" + info.get(0).get("user_id") + "\n" +
                    "玩家: " + info.get(0).get("username") + "\n" +
                    "模式: " + modes + "\n" +
                    "等级: " + (int) Double.parseDouble(info.get(0).get("level").toString()) + "（+" + ll + "）距升级剩" + acc(fen) + "%" + "\n" +
                    "表现: " + acc(info.get(0).get("pp_raw").toString()) + " pp（" + pps + "）" + "\n" +
                    "准确率: " + acc(info.get(0).get("accuracy").toString()) + "%" + "（" + accs + "）" + "\n" +
                    "总次数: " + info.get(0).get("playcount").toString() + "（+" + pc + "）" + "\n" +
                    "总命中: " + add(info.get(0).get("count300").toString(), info.get(0).get("count100").toString(), info.get(0).get("count50").toString()) + "（+" + tth + "）" + "\n" +
                    "成绩: " + StringUtil.fen(info.get(0).get("ranked_score").toString()) + "（" + rankeds + "）" + "\n" +
                    "全球排名: " + info.get(0).get("pp_rank").toString() + "（" + ranks + "）" + "\n";
            if (!update) {
                str += "[注]：括号里的数据是和上一次更新后的数据作比较\n更新需要自己手动更新，具体可查看！help帮助指令";
            } else {
                assert myOSU != null;
                str += "更新时间：" + DateUtils.format(myOSU.getUpdateTime());
            }

        } else {
            str = "找不到 " + username + " 该玩家的信息，你确定不是乱搞的？！";
        }

        return str;
    }

    private static String acc(String s) {
        return String.format("%.2f", Double.parseDouble(s));
    }

    private static Integer add(String t300, String t100, String t50) {
        return Integer.parseInt(t300) + Integer.parseInt(t100) + Integer.parseInt(t50);
    }


    private Osu selInfoByUserId(long userId, Integer mode) {
        String sql = "select o.id from osu o " +
                "where o.user_id = "+userId+" and o.mode = " + mode + " limit 1 ";
        Osu osu = osuDao.findFirst(sql);
        if(null != osu){
            return osuDao.findById(osu.getId());
        }
        return null;
    }


    private void insertData(Map<String, Object> m) {
        Osu myOSU = new Osu();
        myOSU.setUserId(Long.parseLong(m.get("userId").toString()));
        myOSU.setAcc(Double.parseDouble(m.get("acc").toString()));
        myOSU.setLevel(Integer.parseInt(m.get("level").toString()));
        myOSU.setPc(Integer.parseInt(m.get("pc").toString()));
        myOSU.setPp(Double.parseDouble(m.get("pp").toString()));
        myOSU.setRank(Integer.parseInt(m.get("rank").toString()));
        myOSU.setTth(Integer.parseInt(m.get("tth").toString()));
        myOSU.setUsername(m.get("username").toString());
        myOSU.setMode(Integer.parseInt(m.get("mode").toString()));
        myOSU.setCreateTime(new Date());
        myOSU.setUpdateTime(new Date());
        myOSU.setRankscore(m.get("ranked").toString());
        myOSU.save();
    }
}
